;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-

;; Place your private configuration here! Remember, you do not need to run 'doom
;; sync' after modifying this file!


;; Some functionality uses this to identify you, e.g. GPG configuration, email
;; clients, file templates and snippets. It is optional.
;; (setq user-full-name "John Doe"
;;       user-mail-address "john@doe.com")

;; Doom exposes five (optional) variables for controlling fonts in Doom:
;;
;; - `doom-font' -- the primary font to use
;; - `doom-variable-pitch-font' -- a non-monospace font (where applicable)
;; - `doom-big-font' -- used for `doom-big-font-mode'; use this for
;;   presentations or streaming.
;; - `doom-symbol-font' -- for symbols
;; - `doom-serif-font' -- for the `fixed-pitch-serif' face
;;
;; See 'C-h v doom-font' for documentation and more examples of what they
;; accept. For example:
;;
;;(setq doom-font (font-spec :family "Fira Code" :size 12 :weight 'semi-light)
;;      doom-variable-pitch-font (font-spec :family "Fira Sans" :size 13))
;;
;; If you or Emacs can't find your font, use 'M-x describe-font' to look them
;; up, `M-x eval-region' to execute elisp code, and 'M-x doom/reload-font' to
;; refresh your font settings. If Emacs still can't find your font, it likely
;; wasn't installed correctly. Font issues are rarely Doom issues!

;; There are two ways to load a theme. Both assume the theme is installed and
;; available. You can either set `doom-theme' or manually load a theme with the
;; `load-theme' function. This is the default:
(setq doom-theme 'gruber-darker)

;; (setq doom-font (font-spec :family "Sarasa Term SC Nerd" :size 12 :weight 'semi-light))
;; This determines the style of line numbers in effect. If set to `nil', line
;; numbers are disabled. For relative line numbers, set this to `relative'.
(setq display-line-numbers-type 'relative)

;; If you use `org' and don't want your org files in the default location below,
;; change `org-directory'. It must be set before org loads!
(setq org-directory "~/org/")


;; Whenever you reconfigure a package, make sure to wrap your config in an
;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
;;
;;   (after! PACKAGE
;;     (setq x y))
;;
;; The exceptions to this rule:
;;
;;   - Setting file/directory variables (like `org-directory')
;;   - Setting variables which explicitly tell you to set them before their
;;     package is loaded (see 'C-h v VARIABLE' to look up their documentation).
;;   - Setting doom variables (which start with 'doom-' or '+').
;;
;; Here are some additional functions/macros that will help you configure Doom.
;;
;; - `load!' for loading external *.el files relative to this one
;; - `use-package!' for configuring packages
;; - `after!' for running code after a package has loaded
;; - `add-load-path!' for adding directories to the `load-path', relative to
;;   this file. Emacs searches the `load-path' when you load packages with
;;   `require' or `use-package'.
;; - `map!' for binding new keys
;;
;; To get information about any of these functions/macros, move the cursor over
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
;; This will open documentation for it, including demos of how they are used.
;; Alternatively, use `C-h o' to look up a symbol (functions, variables, faces,
;; etc).
;;
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
;; they are implemented.
(setq package-archives '(("gnu"   . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
                         ("org-cn". "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/")
                         ("nongnu". "http://mirrors.tuna.tsinghua.edu.cn/elpa/nongnu/")
                         ("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")))
(use-package! evil-terminal-cursor-changer
  :hook (tty-setup . evil-terminal-cursor-changer-activate))


(after! company
  (setq
   +lsp-company-backends '(company-capf :separate company-dabbrev)
   +company-backend-alist '((text-mode (:separate company-dabbrev company-yasnippet)) ;; company-ispell is annoying for `Start looking process...` in Chinese
                            (web-mode (company-capf :separate company-dabbrev))
                            (go-mode (company-capf :separate company-dabbrev))
                            ;; company-lsp-copilot company-lsp-rocks
                            (prog-mode (company-capf :separate company-dabbrev)) ;;  company-yasnippet 指定 prog-mode 使用 company-tabnine-capf ，使用 rust-analyzer 服务时这个通过 +lsp-company-backend 指定的后端 revert buffer 后总是会被这个配置的值覆盖
                            ;; (prog-mode company-capf) ;;  company-yasnippet 指定 prog-mode 使用 company-tabnine-capf ，使用 rust-analyzer 服务时这个通过 +lsp-company-backend 指定的后端 revert buffer 后总是会被这个配置的值覆盖
                            (conf-mode company-capf company-dabbrev-code company-yasnippet))
   )
  )

(map! "C-c /" #'comment-line)
(defun rc/duplicate-line ()
  "Duplicate current line"
  (interactive)
  (let ((column (- (point) (point-at-bol)))
        (line (let ((s (thing-at-point 'line t)))
                (if s (string-remove-suffix "\n" s) ""))))
    (move-end-of-line 1)
    (newline)
    (insert line)
    (move-beginning-of-line 1)
    (forward-char column)))
                                        ;(global-set-key (kbd "C-,") 'rc/duplicate-line)
(map! "C-c ," #'rc/duplicate-line)
(map! "C-," #'rc/duplicate-line) 
(after! evil-snipe
  (evil-define-key* '(motion normal) evil-snipe-local-mode-map
    "s" #'evil-avy-goto-char-2)
  )

(map!
 :after evil-snipe
 :nv "s" #'evil-avy-goto-char-2
 )

(after! go-mode
  (add-hook 'before-save-hook 'gofmt-before-save)
  (setq tab-width 2)
  (setq gofmt-command "goimports")
  (setq standard-indent 2)
  (setq indent-tabs-mode nil)
  (set-company-backend! 'go-mode '(company-capf :separate company-dabbrev))
  )

(use-package! flycheck
  :config
  (setq-default flycheck-disabled-checkers '(golangci-lint))
  (setq flycheck-check-syntax-automatically '(save mode-enabled)))
;; eglot
(use-package! eglot-booster
  :after eglot
  :config	(eglot-booster-mode))


(use-package! eldoc-box
  :after eldoc
  :config
  (eldoc-box-hover-mode))

(after! company
  (setq company-abort-on-unique-match nil)
  (setq company-idle-delay 0)
  (setq company-minimum-prefix-length 2)
  (setq company-tooltip-idle-delay 0))
(after! company-box
  (setq company-box-doc-delay 0.1))

(after! company-box
  (defun company-box-icons--lsp-copilot (candidate)
    (-when-let* ((copilot-item (get-text-property 0 'lsp-copilot--item candidate))
                 (lsp-item (plist-get copilot-item :item))
                 (kind-num (plist-get lsp-item :kind)))
      (alist-get kind-num company-box-icons--lsp-alist)))

  (setq company-box-icons-functions
        (cons #'company-box-icons--lsp-copilot company-box-icons-functions)))

(after! lsp-mode
(defun lsp-booster--advice-json-parse (old-fn &rest args)
  "Try to parse bytecode instead of json."
  (or
   (when (equal (following-char) ?#)
     (let ((bytecode (read (current-buffer))))
       (when (byte-code-function-p bytecode)
         (funcall bytecode))))
   (apply old-fn args)))
(advice-add (if (progn (require 'json)
                       (fboundp 'json-parse-buffer))
                'json-parse-buffer
              'json-read)
            :around
            #'lsp-booster--advice-json-parse)

(defun lsp-booster--advice-final-command (old-fn cmd &optional test?)
  "Prepend emacs-lsp-booster command to lsp CMD."
  (let ((orig-result (funcall old-fn cmd test?)))
    (if (and (not test?)                             ;; for check lsp-server-present?
             (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper
             lsp-use-plists
             (not (functionp 'json-rpc-connection))  ;; native json-rpc
             (executable-find "emacs-lsp-booster"))
        (progn
          (when-let ((command-from-exec-path (executable-find (car orig-result))))  ;; resolve command from exec-path (in case not found in $PATH)
            (setcar orig-result command-from-exec-path))
          (message "Using emacs-lsp-booster for %s!" orig-result)
          (cons "emacs-lsp-booster" orig-result))
      orig-result)))
(advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command)
	)

(after! corfu
  (setq +corfu-want-minibuffer-completion nil)
  (setq global-corfu-minibuffer nil)
  (setq corfu-auto-delay 0)
  (setq corfu-preselect 'first)
  (setq corfu-preview-current nil))
(after! corfu-popupinfo
  (setq corfu-popupinfo-delay '(0.1 . 0.1)))

(use-package! cj-mode
  :mode "\\.cj\\'")

(use-package! wakatime-mode
  :defer .1
  :config (global-wakatime-mode))

(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(rainbow-delimiters-base-error-face ((t (:inherit rainbow-delimiters-base-face :foreground "#ff5370"))))
 '(rainbow-delimiters-base-face ((t (:inherit default))))
 '(rainbow-delimiters-depth-1-face ((t (:foreground "#c792ea"))))
 '(rainbow-delimiters-depth-2-face ((t (:foreground "#f78c6c"))))
 '(rainbow-delimiters-depth-3-face ((t (:foreground "#c3e88d"))))
 '(rainbow-delimiters-depth-4-face ((t (:foreground "#89DDFF"))))
 '(rainbow-delimiters-depth-5-face ((t (:foreground "#bb80b3"))))
 '(rainbow-delimiters-depth-6-face ((t (:foreground "#ffcb6b"))))
 '(rainbow-delimiters-depth-7-face ((t (:foreground "#82aaff"))))
 '(rainbow-delimiters-depth-8-face ((t (:foreground "#44b9b1"))))
 '(rainbow-delimiters-depth-9-face ((t (:foreground "#80cbc4"))))
 '(rainbow-delimiters-inside-depth-1-face ((t (:inherit rainbow-delimiters-base-face :foreground "#c792ea" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-inside-depth-2-face ((t (:inherit rainbow-delimiters-base-face :foreground "#f78c6c" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-inside-depth-3-face ((t (:inherit rainbow-delimiters-base-face :foreground "#c3e88d" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-inside-depth-4-face ((t (:inherit rainbow-delimiters-base-face :foreground "#89DDFF" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-inside-depth-5-face ((t (:inherit rainbow-delimiters-base-face :foreground "#bb80b3" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-inside-depth-6-face ((t (:inherit rainbow-delimiters-base-face :foreground "#ffcb6b" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-inside-depth-7-face ((t (:inherit rainbow-delimiters-base-face :foreground "#82aaff" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-inside-depth-8-face ((t (:inherit rainbow-delimiters-base-face :foreground "#44b9b1" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-inside-depth-9-face ((t (:inherit rainbow-delimiters-base-face :foreground "#80cbc4" :box (:line-width 1 :color "grey75") :height 1.2 :width normal))))
 '(rainbow-delimiters-mismatched-face ((t (:inherit rainbow-delimiters-unmatched-face))))
 '(rainbow-delimiters-unmatched-face ((t (:foreground "#ff5370" :inverse-video t :weight bold))))


 )
